using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.Package;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Diagnostics;
using Microsoft.VisualStudio;
using System.IO;
using Microsoft.VisualStudio.Shell.Interop;

namespace NBusiness.VisualStudio
{
    internal enum ESharpPropertyPageTag
    {
        AssemblyName,
        RootNamespace,
        ApplicationIcon,
        TargetPlatform,
        TargetPlatformLocation,
        DevelopmentDataSourceConnectionString,
        DatabaseProviderType
    }

    [ComVisible(true), Guid("235BD4D0-A47C-4f42-9B66-910B35E74623")]
    public class ESharpPropertyPage : SettingsPage, EnvDTE80.IInternalExtenderProvider
    {
        #region fields
        private string assemblyName;
        private OutputType outputType = OutputType.Library;
        private string defaultNamespace;
        private string applicationIcon;
        private PlatformType targetPlatform = PlatformType.v2;
        private string targetPlatformLocation;
        #endregion

        /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="GeneralPropertyPage.GeneralPropertyPage"]/*' />
        public ESharpPropertyPage()
        {
            this.Name = SR.GetString(SR.GeneralCaption);
        }

        #region overriden methods
        /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="GeneralPropertyPage.GetClassName"]/*' />
        public override string GetClassName()
        {
            return this.GetType().FullName;
        }

        /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="GeneralPropertyPage.BindProperties"]/*' />
        protected override void BindProperties()
        {
            if (this.ProjectMgr == null)
            {
                Debug.Assert(false);
                return;
            }

            this.assemblyName = this.ProjectMgr.GetProjectProperty(ESharpPropertyPageTag.AssemblyName.ToString(), true);
            
            this.defaultNamespace = this.ProjectMgr.GetProjectProperty(ESharpPropertyPageTag.RootNamespace.ToString(), false);
            this.applicationIcon = this.ProjectMgr.GetProjectProperty(ESharpPropertyPageTag.ApplicationIcon.ToString(), false);

            string targetPlatform = this.ProjectMgr.GetProjectProperty(ESharpPropertyPageTag.TargetPlatform.ToString(), false);

            if (targetPlatform != null && targetPlatform.Length > 0)
            {
                try
                {
                    this.targetPlatform = (PlatformType)Enum.Parse(typeof(PlatformType), targetPlatform);
                }
                catch
                { }
            }

            this.targetPlatformLocation = this.ProjectMgr.GetProjectProperty(ESharpPropertyPageTag.TargetPlatformLocation.ToString(), false);
        }

        /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="GeneralPropertyPage.ApplyChanges"]/*' />
        protected override int ApplyChanges()
        {
            if (this.ProjectMgr == null)
            {
                Debug.Assert(false);
                return VSConstants.E_INVALIDARG;
            }

            this.ProjectMgr.SetProjectProperty(ESharpPropertyPageTag.AssemblyName.ToString(), this.assemblyName);
            this.ProjectMgr.SetProjectProperty(ESharpPropertyPageTag.RootNamespace.ToString(), this.defaultNamespace);
            this.ProjectMgr.SetProjectProperty(ESharpPropertyPageTag.ApplicationIcon.ToString(), this.applicationIcon);
            this.ProjectMgr.SetProjectProperty(ESharpPropertyPageTag.TargetPlatform.ToString(), this.targetPlatform.ToString());
            this.ProjectMgr.SetProjectProperty(ESharpPropertyPageTag.TargetPlatformLocation.ToString(), this.targetPlatformLocation);
            this.IsDirty = false;

            return VSConstants.S_OK;
        }
        #endregion

        #region exposed properties
        /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="GeneralPropertyPage.AssemblyName"]/*' />
        [SRCategoryAttribute(SR.Application)]
        [LocDisplayName(SR.AssemblyName)]
        [SRDescriptionAttribute(SR.AssemblyNameDescription)]
        public string AssemblyName
        {
            get { return this.assemblyName; }
            set { this.assemblyName = value; this.IsDirty = true; }
        }

        /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="GeneralPropertyPage.OutputType"]/*' />
        [SRCategoryAttribute(SR.Application)]
        [LocDisplayName(SR.OutputType)]
        [SRDescriptionAttribute(SR.OutputTypeDescription)]
        public OutputType OutputType
        {
            get { return this.outputType; }
        }

        /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="GeneralPropertyPage.DefaultNamespace"]/*' />
        [SRCategoryAttribute(SR.Application)]
        [LocDisplayName(SR.DefaultNamespace)]
        [SRDescriptionAttribute(SR.DefaultNamespaceDescription)]
        public string DefaultNamespace
        {
            get { return this.defaultNamespace; }
            set { this.defaultNamespace = value; this.IsDirty = true; }
        }

        /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="GeneralPropertyPage.ApplicationIcon"]/*' />
        [SRCategoryAttribute(SR.Application)]
        [LocDisplayName(SR.ApplicationIcon)]
        [SRDescriptionAttribute(SR.ApplicationIconDescription)]
        public string ApplicationIcon
        {
            get { return this.applicationIcon; }
            set { this.applicationIcon = value; this.IsDirty = true; }
        }

        /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="GeneralPropertyPage.ProjectFile"]/*' />
        [SRCategoryAttribute(SR.Project)]
        [LocDisplayName(SR.ProjectFile)]
        [SRDescriptionAttribute(SR.ProjectFileDescription)]
        [AutomationBrowsable(false)]
        public string ProjectFile
        {
            get { return Path.GetFileName(this.ProjectMgr.ProjectFile); }
        }

        /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="GeneralPropertyPage.ProjectFolder"]/*' />
        [SRCategoryAttribute(SR.Project)]
        [LocDisplayName(SR.ProjectFolder)]
        [SRDescriptionAttribute(SR.ProjectFolderDescription)]
        [AutomationBrowsable(false)]
        public string ProjectFolder
        {
            get { return Path.GetDirectoryName(this.ProjectMgr.ProjectFolder); }
        }

        /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="GeneralPropertyPage.OutputFile"]/*' />
        [SRCategoryAttribute(SR.Project)]
        [LocDisplayName(SR.OutputFile)]
        [SRDescriptionAttribute(SR.OutputFileDescription)]
        [AutomationBrowsable(false)]
        public string OutputFile
        {
            get
            {
                return this.assemblyName + ESharpProjectNode.GetOuputExtension(this.outputType);
            }
        }

        /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="GeneralPropertyPage.TargetPlatform"]/*' />
        [SRCategoryAttribute(SR.Project)]
        [LocDisplayName(SR.TargetPlatform)]
        [SRDescriptionAttribute(SR.TargetPlatformDescription)]
        [AutomationBrowsable(false)]
        public PlatformType TargetPlatform
        {
            get { return PlatformType.v2; }
        }
       
        #endregion

        #region IInternalExtenderProvider Members

        bool EnvDTE80.IInternalExtenderProvider.CanExtend(string extenderCATID, string extenderName, object extendeeObject)
        {
            IVsHierarchy outerHierarchy = HierarchyNode.GetOuterHierarchy(this.ProjectMgr);
            if (outerHierarchy is EnvDTE80.IInternalExtenderProvider)
                return ((EnvDTE80.IInternalExtenderProvider)outerHierarchy).CanExtend(extenderCATID, extenderName, extendeeObject);
            return false;
        }

        object EnvDTE80.IInternalExtenderProvider.GetExtender(string extenderCATID, string extenderName, object extendeeObject, EnvDTE.IExtenderSite extenderSite, int cookie)
        {
            IVsHierarchy outerHierarchy = HierarchyNode.GetOuterHierarchy(this.ProjectMgr);
            if (outerHierarchy is EnvDTE80.IInternalExtenderProvider)
                return ((EnvDTE80.IInternalExtenderProvider)outerHierarchy).GetExtender(extenderCATID, extenderName, extendeeObject, extenderSite, cookie);
            return null;
        }

        object EnvDTE80.IInternalExtenderProvider.GetExtenderNames(string extenderCATID, object extendeeObject)
        {
            IVsHierarchy outerHierarchy = HierarchyNode.GetOuterHierarchy(this.ProjectMgr);
            if (outerHierarchy is EnvDTE80.IInternalExtenderProvider)
                return ((EnvDTE80.IInternalExtenderProvider)outerHierarchy).GetExtenderNames(extenderCATID, extendeeObject);
            return null;
        }

        #endregion

        #region ExtenderSupport
        [Browsable(false)]
        [AutomationBrowsable(false)]
        public virtual string ExtenderCATID
        {
            get
            {
                Guid catid = this.ProjectMgr.ProjectMgr.GetCATIDForType(this.GetType());
                if (Guid.Empty.CompareTo(catid) == 0)
                    throw new NotImplementedException();
                return catid.ToString("B");
            }
        }
        [Browsable(false)]
        [AutomationBrowsable(false)]
        public object ExtenderNames
        {
            get
            {
                EnvDTE.ObjectExtenders extenderService = (EnvDTE.ObjectExtenders)this.ProjectMgr.GetService(typeof(EnvDTE.ObjectExtenders));
                return extenderService.GetExtenderNames(this.ExtenderCATID, this);
            }
        }
        public object get_Extender(string extenderName)
        {
            EnvDTE.ObjectExtenders extenderService = (EnvDTE.ObjectExtenders)this.ProjectMgr.GetService(typeof(EnvDTE.ObjectExtenders));
            return extenderService.GetExtender(this.ExtenderCATID, extenderName, this);
        }
        #endregion

    }
}
